#include <stdio.h>
#include <stdlib.h>

struct tnodo
{
    int dato;
    struct tnodo * siguiente;
};

void insertar_por_cabecera(struct tnodo * * lista, int valor)
{
    struct tnodo * nuevo = (struct tnodo *) malloc(sizeof(struct tnodo));
    nuevo->dato = valor;
    nuevo->siguiente = *lista;
    *lista = nuevo;
}

void insertar_por_cola(struct tnodo * *lista, int valor)
{
    struct tnodo * actual;

    // Creo el nodo nuevo
    struct tnodo * nuevo = (struct tnodo *) malloc(sizeof(struct tnodo));
    nuevo->dato = valor;
    nuevo->siguiente = NULL;

    if (*lista == NULL)
    {
        // Si la lista está vacía la creo
        *lista = nuevo;
    }
    else
    {
        // Si no, recorro la lista hasta el final y
        actual = *lista;
        while (actual->siguiente != NULL)
        {
            actual = actual->siguiente;
        }
        // El último puntero lo asigno
        actual->siguiente = nuevo;
    }
}

void insertar_en_orden(struct tnodo * *lista, int valor)
{
    struct tnodo * actual;

    // Creo el nodo nuevo
    struct tnodo * nuevo = (struct tnodo *) malloc(sizeof(struct tnodo));
    nuevo->dato = valor;
    nuevo->siguiente = NULL;

    if (*lista == NULL)
    {
        // Si la lista está vacía la creo
        *lista = nuevo;
    }
    else
    {
        actual = *lista;
        // Si es el menor de la lista
        if (actual->dato > valor)
        {
            nuevo->siguiente = actual;
            *lista = nuevo;
        }
        else
        {
            // Si no, recorro la lista hasta el final o donde debo insertarlo y
            while (actual->siguiente != NULL && valor >= actual->siguiente->dato)
            {
                actual = actual->siguiente;
            }
            // Asigno los punteros
            nuevo->siguiente = actual->siguiente;
            actual->siguiente = nuevo;
        }
    }
}

void borrar_lista(struct tnodo * *lista)
{
    struct tnodo * nodo;

    while (*lista != NULL)
    {
        nodo = *lista;
        *lista = nodo->siguiente;
        free(nodo);
    }
}

void mostrar(struct tnodo * lista)
{
    struct tnodo * actual = lista;

    printf("Lista:\n");
    while (actual != NULL)
    {
        printf("%d\t", actual->dato);
        actual = actual->siguiente;
    }
    printf("\n");
}

main()
{
    struct tnodo * lista1 = NULL;
    struct tnodo * lista2 = NULL;
    struct tnodo * lista3 = NULL;

    insertar_por_cabecera(&lista1, 1);
    insertar_por_cabecera(&lista1, 3);
    insertar_por_cabecera(&lista1, 2);
    mostrar(lista1);
    borrar_lista(&lista1);

    insertar_por_cola(&lista2, 1);
    insertar_por_cola(&lista2, 3);
    insertar_por_cola(&lista2, 2);
    mostrar(lista2);
    borrar_lista(&lista2);

    insertar_en_orden(&lista3, 3);
    insertar_en_orden(&lista3, 1);
    insertar_en_orden(&lista3, 2);
    mostrar(lista3);
    borrar_lista(&lista3);

    getch();
}
